/*
 * 验证使用循环引用的shared_ptr将导致内存泄漏，
 * 将其中一方的shared_ptr修改为weak_ptr可解决内存泄漏问题
 *
 */
#include <iostream>
#include <memory>

class A;

class B {
public:
    ~B()
    {
        std::cout << "B destory, a_ptr use_count:" << a_ptr.use_count() << "\n";
    }

    std::shared_ptr<A> a_ptr;
};

// 循环引用B,会引起内存泄漏
class A {
public:
    ~A()
    {
        std::cout << "A destory, b_ptr use_count:" << b_ptr.use_count() << "\n";
    }

    std::shared_ptr<B> b_ptr;
};

class D;
// 验证使用 weak_ptr 解决循环引用引起的内存泄漏问题
class C {
public:
    ~C()
    {
        std::cout << "C destory, c_ptr use_count:" << c_ptr.use_count() << "\n";
    }

    std::shared_ptr<D> c_ptr;
};

class D {
public:
    ~D()
    {
        std::cout << "D destory, d_ptr use_count:" << d_ptr.use_count() << "\n";
    }

    std::weak_ptr<C> d_ptr;
};

int main()
{
    std::shared_ptr<A> a(new A());
    std::shared_ptr<B> b(new B());
    a->b_ptr = b;
    b->a_ptr = a;

    std::cout << "A:" << a.use_count() << "\n";
    std::cout << "B" << b.use_count() << "\n";

    std::shared_ptr<C> c(new C());
    std::shared_ptr<D> d(new D());
    c->c_ptr = d;
    d->d_ptr = c;

    std::cout << "C:" << c.use_count() << "\n";
    std::cout << "D" << d.use_count() << "\n";
    // 程序结束也没有释放a/b

}
